﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Tradex.Trading {

    /// <summary>
    /// The order class contains all information about the current status of an order. This is a dynamic object that can
    /// be updated by messages. It has no history information, so updates overwrite the shown info.
    /// </summary>
    public sealed class Order : ComponentModel.DynamicObject {

        /// <summary>
        /// This is the pubic  constructor for the Order object.
        /// </summary>
        /// <param name="key"></param>
        public Order(OrderKey key) {
            Key = key;
        }


        /// <inheritdoc />
        public override void ProcessMessage(Messages.Message message) {
            if (message == null) {
                return;
            }
            switch (message.Code) {
                case Messages.MessageCode.OrderUpdate:
                    // New order information to deposit ;)
                    Messages.OrderUpdateMessage update = (Messages.OrderUpdateMessage)message;
                    if (update.ConnectionKey != null) {
                        if (ConnectionKey != null && ConnectionKey != update.ConnectionKey) {
                            throw new ArgumentException("Invalid ConnectionKey");
                        }
                        ConnectionKey = update.ConnectionKey;
                    }
                    // Do we have a new progress?
                    if (update.Progress != null) {
                        if (Update != null || update.Progress.Timestamp > Update.Timestamp) {
                            Update = update.Progress;
                        }
                    }
                    // Do we have a new execution?
                    if (update.Execution != null) {
                        if (Execution != null ||update.Execution.Timestamp > Execution.Timestamp) {
                            Execution = update.Execution;
                        }
                    }
                    break;
            }
        }

        /// <summary>
        /// This is the Key of the order.
        /// </summary>
        public OrderKey Key { get; private set; }

        /// <summary>
        /// This is the connection key of the order. This is the unique identifier the order
        /// has on the connection.
        /// </summary>
        public OrderId ConnectionKey {
            get {
                lock (this) {
                    return _ConnectionKey;
                }
            }
            private set {
                lock (this) {
                    OnPropertyChanged("ConnectionKey", ref _ConnectionKey, value);
                }
            }
        }
        OrderId _ConnectionKey;

        /// <summary>
        /// This is the OrderInfo for the order object. It contains the generic order information
        /// (what to buy at which price etc.) and changes rarely (either by user interaction
        /// or by the exchange rewriting the order, but not by updates).
        /// </summary>
        public OrderInfo Info {
            get {
                lock (this) {
                    return _Info;
                }
            }
            set {
                lock (this) {
                    OnPropertyChanged("Info", ref _Info, value);
                }
            }
        }
        OrderInfo _Info;

        /// <summary>
        /// The Update property contains the last update to the order that was sent from the connector.
        /// The update contains information like the current execution progress and messages from the
        /// executing instance.
        /// </summary>
        public OrderUpdate Update {
            get {
                lock (this) {
                    return _Progress;
                }
            }
            private set {
                lock (this) {
                    OnPropertyChanged("Update", ref _Progress, value);
                }
            }
        }
        OrderUpdate _Progress;

        /// <summary>
        /// The Execution property contains the last execution associated with the order. Cumulative execution
        /// information is available as part of the Update property.
        /// </summary>
        public OrderExecution Execution {
            get {
                lock (this) {
                    return _Execution;
                }
            }
            private set {
                lock (this) {
                    OnPropertyChanged("Execution", ref _Execution, value);
                }
            }
        }
        OrderExecution _Execution;

    }

}
